package com.net.xpay.core.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayDataBillEreceiptApplyModel;
import com.alipay.api.response.AlipayDataBillEreceiptApplyResponse;
import com.alipay.api.response.AlipayDataBillEreceiptQueryResponse;
import com.google.common.base.Preconditions;
import com.net.xpay.common.domain.PayTransReceipt;
import com.net.xpay.common.domain.User;
import com.net.xpay.common.enums.safePay.ApplyReceiptStatus;
import com.net.xpay.common.manager.PayTransReceiptManager;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.common.exception.BusinessException;
import com.net.xpay.alipay.PoseidonAlipayClient;
import com.net.xpay.core.domain.AlipayUser;
import com.net.xpay.core.domain.PayTrans;
import com.net.xpay.core.enums.PayTransStatus;
import com.net.xpay.core.manager.AlipayUserManager;
import com.net.xpay.core.manager.PayTransManager;
import com.net.xpay.core.service.PayTransReceiptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
@Slf4j
public class PayTransReceiptServiceImpl implements PayTransReceiptService {

    @Autowired
    private PayTransManager payTransManager;

    @Autowired
    private PayTransReceiptManager payTransReceiptManager;

    @Autowired
    private PoseidonAlipayClient xpayAlipayClient;

    @Autowired
    private AlipayUserManager alipayUserManager;

    @Override
    public PayTransReceipt updateReceiptFile(Long id) {
        Preconditions.checkArgument(id != null);

        PayTransReceipt receipt = payTransReceiptManager.getById(id);

        if (receipt.getStatus() != ApplyReceiptStatus.INIT) {
            return receipt;
        }

        PayTrans payTrans = payTransManager.getById(receipt.getPayTransId());
        AlipayUser alipayUser = alipayUserManager.getById(payTrans.getAlipayUserId());
        try {
            AlipayDataBillEreceiptQueryResponse resp = xpayAlipayClient.queryAlipayDataBillEreceipt(receipt.getFileId(), alipayUser.getAuthToken());
            if (!resp.isSuccess()) {
                log.info("updateReceiptFile fail id={}|error={}", id, resp.getCode() + "|" + resp.getSubCode() + "|" + resp.getMsg() + "|" + resp.getSubMsg());
                throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "查询失败:" + resp.getMsg() + "|" + resp.getSubMsg());
            }

            if (resp.getStatus().equals(ApplyReceiptStatus.SUCCESS.getValue())) {
                //成功了
                receipt.setStatus(ApplyReceiptStatus.SUCCESS);
                receipt.setDownloadUrl(resp.getDownloadUrl());
                receipt.setEndTime(LocalDateTime.now());
            } else if (resp.getStatus().equals(ApplyReceiptStatus.FAIL.getValue())){
                receipt.setStatus(ApplyReceiptStatus.FAIL);
                receipt.setErrorMessage(resp.getErrorMessage());
                receipt.setEndTime(LocalDateTime.now());
                receipt.setErrorMessage("文件生成超时");
            }
            payTransReceiptManager.update(receipt);
            return receipt;
        } catch (AlipayApiException e) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "支付宝接口异常");
        }
    }


    @Override
    public PayTransReceipt applyPayTransBillFile(User user, Long payTransId) {
        log.info("applyPayTransBillFile userId={}|payTransId={}", user.getId(), payTransId);

        PayTrans payTrans = payTransManager.findById(user.getId(), payTransId);

        if (payTrans.getStatus() != PayTransStatus.SUCCESS) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "当前转账未成功无法下载回单");
        }
        if (payTrans.getDetailId() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "无法下载回单");
        }
        //查询一下是否已经在处理中了
        PayTransReceipt payTransReceipt = payTransReceiptManager.findByPayTransId(payTrans.getUserId(), payTrans.getId());
        if (payTransReceipt != null) {
            //不是处理中，申请提交
            return reApplyPayTransBillFile(payTransReceipt);
        } else {
            return doApplyPayTransBillFile(payTrans);
        }
    }

    private PayTransReceipt doApplyPayTransBillFile(PayTrans payTrans) {
        AlipayUser alipayUser = alipayUserManager.getById(payTrans.getAlipayUserId());
        AlipayDataBillEreceiptApplyModel applyModel = new AlipayDataBillEreceiptApplyModel();
        applyModel.setKey(payTrans.getDetailId());
        AlipayDataBillEreceiptApplyResponse resp;
        try {
            resp = xpayAlipayClient.applyAlipayDataBillEreceipt(applyModel, alipayUser.getAuthToken());
            if (!resp.isSuccess() || resp.getFileId() == null) {
                log.warn("doApplyPayTransBillFile failed userId={}|id={}|msg={}|subMsg={}|code={}|subCode={}", payTrans.getUserId(), payTrans.getId(), resp.getMsg(), resp.getSubMsg(), resp.getCode(), resp.getSubCode());
                throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "申请回单失败：" + resp.getMsg() + "|" + resp.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "系统繁忙，请稍后再试");
        }

        PayTransReceipt receipt = new PayTransReceipt();
        receipt.setUserId(payTrans.getUserId());
        receipt.setPayTransId(payTrans.getId());
        receipt.setDetailId(payTrans.getDetailId());
        receipt.setFileId(resp.getFileId());
        receipt.setLastApplyTime(LocalDateTime.now());
        receipt.setStatus(ApplyReceiptStatus.INIT);
        receipt.setNextQueryTime(LocalDateTime.now());
        receipt.setQueryCount(0);

        payTransReceiptManager.save(receipt);

        return receipt;
    }

    private PayTransReceipt reApplyPayTransBillFile(PayTransReceipt payTransReceipt) {
        if (payTransReceipt.getStatus() == ApplyReceiptStatus.INIT || payTransReceipt.getStatus() == ApplyReceiptStatus.PROCESS) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "回单已申请，正在处理中");
        }
        PayTrans payTrans = payTransManager.getById(payTransReceipt.getPayTransId());
        AlipayUser alipayUser = alipayUserManager.getById(payTrans.getAlipayUserId());
        AlipayDataBillEreceiptApplyModel applyModel = new AlipayDataBillEreceiptApplyModel();
        applyModel.setKey(payTransReceipt.getDetailId());
        AlipayDataBillEreceiptApplyResponse resp;
        try {
            resp = xpayAlipayClient.applyAlipayDataBillEreceipt(applyModel, alipayUser.getAuthToken());
            if (!resp.isSuccess() || resp.getFileId() == null) {
                log.warn("reApplyPayTransBillFile failed userId={}|id={}|msg={}|subMsg={}|code={}|subCode={}", payTransReceipt.getUserId(), payTransReceipt.getId(), resp.getMsg(), resp.getSubMsg(), resp.getCode(), resp.getSubCode());
                throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "申请回单失败：" + resp.getMsg() + "|" + resp.getSubMsg());
            }
        } catch (AlipayApiException e) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "系统繁忙，请稍后再试");
        }
        payTransReceipt.setFileId(resp.getFileId());
        payTransReceipt.setLastApplyTime(LocalDateTime.now());
        payTransReceipt.setStatus(ApplyReceiptStatus.INIT);
        payTransReceipt.setEndTime(null);
        payTransReceipt.setNextQueryTime(LocalDateTime.now());
        payTransReceipt.setQueryCount(0);

        payTransReceiptManager.update(payTransReceipt);
        return payTransReceipt;
    }
}
